﻿using System;
using System.Collections.Generic;
using System.Linq;
using Notoric.Commanding;
using Notoric.Gui.Windows;
using Notoric.ViewModel.Elements.CWNotation;

namespace Notoric.Gui.Commands
{
    /// <summary>
    /// Implements a command for splitting a selected group of beamed symbols.
    /// </summary>
    public class SplitBeamGroupCommand : MusicSelectionRibbonCommand
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SplitBeamGroupCommand"/> class.
        /// </summary>
        /// <param name="mainWindow">
        /// <para>
        /// Type: <see cref="MainWindow"/>
        /// </para>
        /// <para>
        /// The main application window.
        /// </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="mainWindow"/> is <see langword="null"/>.
        /// </exception>
        public SplitBeamGroupCommand(MainWindow mainWindow)
            : base(mainWindow)
        {
            ScreenTipTitle = "Split Beam";
            ScreenTipText = "Removes the beam from the selected group of symbols.";
            DisableReason = "Select one or more beamed symbols.";
        }

        #endregion

        #region MusicSelectionRibbonCommand Members

        /// <inheritdoc/>
        protected override bool CanExecuteCore(object parameter)
        {
            var durSymbols = from symbol in Selection
                             where symbol is DurationalSymbol
                             select symbol as DurationalSymbol;

            return durSymbols.Count(s => s.GroupBeam != null) > 0;
        }

        #endregion

        #region ICommand Members

        /// <inheritdoc/>
        public override void Execute(object parameter)
        {
            var durSymbols = from symbol in Selection.OrderByBeat()
                             where symbol is DurationalSymbol
                             select (DurationalSymbol)symbol;
            var beamGroups = from symbol in durSymbols
                             where symbol.GroupBeam != null
                             group symbol by symbol.GroupBeam into g
                             select new { GroupBeam = g.Key, Symbols = g };

            var macro = new UndoableMacroCommand(ApplicationWindow.StackManager.ActiveUndoStack, ApplicationWindow.StackManager.ActiveRedoStack);

            foreach (var g in beamGroups)
                macro.Commands.Add(
                    new ViewModel.SplitBeamGroupCommand(macro.UndoStack, macro.RedoStack)
                    {
                        Symbols = new List<DurationalSymbol>(g.Symbols)
                    }
                    );

            macro.Execute(null);
        }

        #endregion
    }
}
